package cn.itcast.up.up_web.service.impl;

import cn.itcast.up.common.OozieParam;
import cn.itcast.up.common.OozieUtils;
import cn.itcast.up.up_web.bean.dto.ModelDto;
import cn.itcast.up.up_web.bean.dto.TagDto;
import cn.itcast.up.up_web.bean.dto.TagModel;
import cn.itcast.up.up_web.bean.po.ModelPo;
import cn.itcast.up.up_web.bean.po.TagPo;
import cn.itcast.up.up_web.repo.ModelRepository;
import cn.itcast.up.up_web.repo.TagRepository;
import cn.itcast.up.up_web.service.EngineService;
import cn.itcast.up.up_web.service.TagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import scala.annotation.meta.param;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

/**
 * 标签服务层具体实现
 */
@Service
public class TagServiceImpl implements TagService {

    @Autowired
    private TagRepository tagRepository;
    @Autowired
    private ModelRepository modelRepository;
    @Autowired
    private EngineService engine;

    @Override
    public List<TagDto> findTagsByPid(Long pid) {
        // 通过pid查询对应的标签
        List<TagPo> list = tagRepository.findByPid(pid);
        // 将po类型转换为dto类型.
        // for循环,在循环中进行转换
//        for (TagPo tagPo : list) {
//            TagDto dto = convert(tagPo);
//        }

//        list.stream().map((po) -> {
//            return convert(po);
//        })
        List<TagDto> dtoList = list.stream().map(this::convert).collect(Collectors.toList());
        return dtoList;
    }

    @Override
    public void saveTags(List<TagDto> list) {
        // 先将对象转换为po
        List<TagPo> poList = list.stream().map(this::convert).collect(Collectors.toList());
        //将数据保存到数据库.
        TagPo po1 = poList.get(0);
        TagPo po2 = poList.get(1);
        TagPo po3 = poList.get(2);
        // 先保存1级,保存过1级后就可以拿到1级的ID,
        // 保存之前,是否需要看数据库中有当前数据?
        // 同一个父ID下面不能有重复的名字.
        TagPo tmpPo = null;
        tmpPo = tagRepository.findByPidAndName(po1.getPid(), po1.getName());
        // 如果tmpPo == null, 那么就进行保存
        if (tmpPo == null) {
            tmpPo = tagRepository.save(po1);
        }
        // 用1级的ID作为2级的父ID,保存2级
        po2.setPid(tmpPo.getId());
        tmpPo = tagRepository.findByPidAndName(po2.getPid(), po2.getName());
        if (tmpPo == null) {
            tmpPo = tagRepository.save(po2);
        }
        // 用2级的ID作为3级的父ID,保存3级.
        po3.setPid(tmpPo.getId());
        tmpPo = tagRepository.findByPidAndName(po3.getPid(), po3.getName());
        if (tmpPo == null) {
            tmpPo = tagRepository.save(po3);
        }

    }

    /**
     * 添加4级标签
     *
     * @param tagModel
     */
    @Override
    public void saveTagModel(TagModel tagModel) {
        TagDto tag = tagModel.getTag();
        ModelDto model = tagModel.getModel();
        // 保存数据的时候需要先保存4级标签,获取到4级标签的ID之后再去保存模型.
        TagPo tagPo = tagRepository.findByPidAndName(tag.getPid(), tag.getName());
        if (tagPo == null) {
            tagPo = tagRepository.save(convert(tag));
        }
        // 将modeldto对象转换为po对象
        ModelPo modelPo = convert(model, tagPo.getId());
        //保存modelpo对象
        modelRepository.save(modelPo);
    }

    /**
     * 查询PID的标签和模型
     *
     * @param pid
     * @return
     */
    @Override
    public List<TagModel> findTagModel(Long pid) {
        // 定义保存最终结果的集合
        List<TagModel> tagModels = new ArrayList<>();

        //根据pid查询4级的标签信息.获取4级标签所对应的模型信息.
        List<TagPo> tagList = tagRepository.findByPid(pid);
        // 遍历4级标签信息
        for (TagPo tagPo : tagList) {
            // 获取模型信息.
            ModelPo modelPo = null;
            // 判断当前的tag是4级还是5级.
            // 如果是4级,那么就获取模型,如果是5级,不获取模型信息.
            if (tagPo.getLevel() == 4) {
                // 获取模型
                modelPo = modelRepository.findByTagId(tagPo.getId());
            } else {
                // 如果是5级,什么都不做.
            }
            tagModels.add(new TagModel(convert(tagPo), convert(modelPo)));
        }

        return tagModels;
    }

    /**
     * 保存5级标签
     *
     * @param dto
     */
    @Override
    public void saveTag(TagDto dto) {
        tagRepository.save(convert(dto));
    }


    @Override
    public void updateModelState(Long id, Integer state) {
        ModelPo modelPo = modelRepository.findByTagId(id);
        if (state == ModelPo.STATE_ENABLE) {
            //启动流程
            engine.startModel(convert(modelPo));
        }
        if (state == ModelPo.STATE_DISABLE) {
            //关闭流程
            engine.stopModel(convert(modelPo));
        }
        //更新状态信息
        modelPo.setState(state);
        modelRepository.save(modelPo);
    }


    /**
     * 转换model的po对象为dto对象
     *
     * @param modelPo
     * @return
     */
    private ModelDto convert(ModelPo modelPo) {
        // 先判断modelPo是否为空,如果是5级的标签,是没有model的
        if (modelPo == null) {
            return null;
        }

        return new ModelDto(
                modelPo.getId(),
                modelPo.getName(),
                modelPo.getMainClass(),
                modelPo.getPath(),
                modelPo.getArgs(),
                ModelDto.parseDate(modelPo.getSchedule()),
                modelPo.getState()
        );
    }

    /**
     * 模型的dto转换为po
     *
     * @param dto
     * @return
     */
    public ModelPo convert(ModelDto dto, Long tagID) {
        return new ModelPo(dto.getId(),
                tagID,
                dto.getName(),
                dto.getState(),
                dto.getPath(),
                dto.getMainClass(),
                dto.getSchedule().toPattern(),
                dto.getArgs(),
                new Date(),
                new Date()
        );
    }


    /**
     * 将标签的dto对象转换为po对象
     *
     * @param dto
     * @return
     */
    private TagPo convert(TagDto dto) {
        TagPo tagPo = new TagPo();
        tagPo.setId(dto.getId());
        tagPo.setName(dto.getName());
        // 如果当前的等级是1级,那么直接给pid一个-1.
        if (dto.getLevel() != null && dto.getLevel() == 1) {
            tagPo.setPid(-1L);
        } else {
            tagPo.setPid(dto.getPid());
        }
        tagPo.setRule(dto.getRule());
        tagPo.setLevel(dto.getLevel());
        tagPo.setState(dto.getState());
        return tagPo;
    }


    /**
     * 将标签的po对象转换为dto对象
     *
     * @param po
     * @return
     */
    private TagDto convert(TagPo po) {
        return new TagDto(po.getId(), po.getName(), po.getRule(), po.getLevel(), po.getPid(), po.getState());
    }


}
